#include <stdlib.h>
#include <string.h>
#include "lsoh_nvmem_io.h"
#include "lsoh_nvmem_mtd_io.h"

extern nv_var_field ls_nv_var_set[];
extern nv_var_io_func_set ls_nv_var_io_func_set;

#define LS_NV_PACKAGE_FRONT_LEN 4
#define LS_NV_PACKAGE_BACK_LEN 4

const char* ls_oh_nv_package_front = "LSOH";
const char* ls_oh_nv_package_back = "LSOH";

#define NV_PACKAGE_LEN(x) (LS_NV_PACKAGE_FRONT_LEN + x + LS_NV_PACKAGE_BACK_LEN)

static int nv_var_type_invaild(nv_var_type var_type);
static int nv_var_package_invaild(unsigned char* buf, int size);
static int package_nv_var(unsigned char* package, unsigned char* buf, int size);

int nv_var_read(nv_var_type var_type, unsigned char** buf)
{
	int res;
	int package_size;
	int buf_size;
	unsigned char* package = 0;
	if (nv_var_type_invaild(var_type) || !buf || buf[0])
	{
		return -1;
	}

	buf_size = ls_nv_var_set[var_type].size;
	package_size = NV_PACKAGE_LEN(buf_size);
	package = (unsigned char*)calloc(package_size, sizeof(unsigned char));
	// io
	res = ls_nv_var_io_func_set.read_var(ls_nv_var_set + var_type, package, package_size);

	// 解析是不是 前后格式一致
	if (nv_var_package_invaild(package, package_size) || res)
	{
		free(package);
		package = 0;
		return -1;
	}

	// 预留多一个位置, 当作字符串
	buf[0] = (unsigned char*)calloc(buf_size + 1, sizeof(unsigned char));
	memcpy(buf[0], package + (LS_NV_PACKAGE_FRONT_LEN), buf_size);
	free(package);
	package = 0;

	return 0;
}

int nv_var_write(nv_var_type var_type, unsigned char* buf)
{
	int res;
	int package_size;
	int buf_size;
	unsigned char* package = 0;
	if (nv_var_type_invaild(var_type) || !buf)
	{
		return -1;
	}

	buf_size = ls_nv_var_set[var_type].size;
	package_size = NV_PACKAGE_LEN(buf_size);
	package = (unsigned char*)calloc(package_size, sizeof(unsigned char));

	// 添加前后格式包 ls_oh_nv_package_front ls_oh_nv_package_back
	package_nv_var(package, buf, buf_size);
	// io
	res = ls_nv_var_io_func_set.write_var(ls_nv_var_set + var_type, package, package_size);

	return res ? -1 : 0;
}

int get_nv_var_size(nv_var_type var_type)
{
	if (nv_var_type_invaild(var_type))
	{
		return -1;
	}
	return ls_nv_var_set[var_type].size;
}

static int nv_var_type_invaild(nv_var_type var_type)
{
	return (var_type < 0 || var_type >= NV_TYPE_MAX);
}

static int nv_var_package_invaild(unsigned char* buf, int size)
{
	int res = 0;
	if (!buf)
	{
		return 1;
	}
	res += memcmp(buf, ls_oh_nv_package_front, LS_NV_PACKAGE_FRONT_LEN);
	res += memcmp(buf + (size - LS_NV_PACKAGE_BACK_LEN), ls_oh_nv_package_back, LS_NV_PACKAGE_BACK_LEN);
	return res ? 1 : 0;
}

static int package_nv_var(unsigned char* package, unsigned char* buf, int size)
{
	if (!package || !buf)
	{
		return -1;
	}
	memcpy(package, ls_oh_nv_package_front, LS_NV_PACKAGE_FRONT_LEN);
	memcpy(package + LS_NV_PACKAGE_FRONT_LEN, buf, size);
	memcpy(package + LS_NV_PACKAGE_FRONT_LEN + size, ls_oh_nv_package_back, LS_NV_PACKAGE_BACK_LEN);
	return 0;
}